package com.yy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.yy.domain.ProdProp;
import com.yy.domain.ProdPropValue;
import com.yy.dto.PageDTO;
import com.yy.dto.PropAddDTO;
import com.yy.dto.PropQueryDTO;
import com.yy.ex.BusinessException;
import com.yy.mapper.ProdPropValueMapper;
import com.yy.service.ProdPropService;
import com.yy.mapper.ProdPropMapper;
import com.yy.utils.AuthUtil;
import com.yy.vo.ProdPropVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author yy5
* @description 针对表【prod_prop(规格表)】的数据库操作Service实现
* @createDate 2023-11-27 20:47:04
*/
@Service
public class ProdPropServiceImpl extends ServiceImpl<ProdPropMapper, ProdProp>
    implements ProdPropService{

    @Autowired
    private ProdPropMapper prodPropMapper;
    @Autowired
    private ProdPropValueMapper prodPropValueMapper;
    /**
     * 分页查询规格和规格值
     * 查规格
     * 给每一个规格绑定他对应的规格值集合
     * 1.join
     * 2.查到规格集合  循环 查 对应的规格值的集合
     * 3.查到规格数据 拿到ids 查规格值的数据 在内存中做join
     * @param pageDTO
     * @param propQueryDTO
     * @return
     */
    @Override
    public Page<ProdPropVo> loadProdPropVoPage(PageDTO pageDTO, PropQueryDTO propQueryDTO) {
        Page<ProdProp> page=new Page<>(pageDTO.getCurrent(),pageDTO.getSize());
        Page<ProdPropVo> prodPropVoPage=new Page<>(pageDTO.getCurrent(),page.getSize());
        //拿到商铺id
        Long shopId = AuthUtil.getShopId();
        //查询规格
        Page<ProdProp> prodPropPage=prodPropMapper.selectPage(page,new LambdaQueryWrapper<ProdProp>()
                .eq(!shopId.equals(1L),ProdProp::getShopId,shopId)
                .like(StringUtils.hasText(propQueryDTO.getPropName()),ProdProp::getPropName,propQueryDTO.getPropName())
        );
        List<ProdProp> prodPropList=prodPropPage.getRecords();
        if (CollectionUtils.isEmpty(prodPropList)){
            return prodPropVoPage;
        }
        //获取规格的id集合，做批量查询
        List<Long> prodIds=prodPropList.stream()
                .map(ProdProp::getPropId)
                .collect(Collectors.toList());
        //查询规格值
        List<ProdPropValue> prodPropValues=prodPropValueMapper.selectList(new LambdaQueryWrapper<ProdPropValue>()
                .in(ProdPropValue::getPropId,prodIds)
        );
        List<ProdPropVo> prodPropVos=new ArrayList<>(prodPropList.size());
        //内存中做处理
        Map<Long,List<ProdPropValue>> map=prodPropValues.stream()
                .collect(Collectors.groupingBy(ProdPropValue::getPropId));
        prodPropList.forEach(prodProp -> {
            List<ProdPropValue> propValueList=map.get(prodProp.getPropId());
            ProdPropVo prodPropVo=new ProdPropVo();
            BeanUtils.copyProperties(prodProp,prodPropVo);
            prodPropVo.setProdPropValues(propValueList);
            prodPropVos.add(prodPropVo);
        });
        prodPropVoPage.setRecords(prodPropVos);
        prodPropVoPage.setTotal(prodPropPage.getTotal());
        return prodPropVoPage;

    }

    /**
     * 新增规格和规格值
     * 不要再循环中操作数据库 （加了事务除外）
     * 不要再循环中发起远程调用
     * @param propAddDTO
     * @param shopId
     * @return
     */
    @Override
    public Integer addPropAndVals(PropAddDTO propAddDTO, Long shopId) {
        Long count=prodPropMapper.selectCount(new LambdaQueryWrapper<ProdProp>()
                .eq(ProdProp::getShopId,shopId)
                .eq(ProdProp::getPropName,propAddDTO.getPropName())
        );
        if (count>0){
            throw new BusinessException("该商品规格已存在");
        }
        ProdProp prodProp=new ProdProp();
        prodProp.setShopId(shopId);
        prodProp.setPropName(propAddDTO.getPropName());
        prodProp.setRule(1);
        int insert = this.prodPropMapper.insert(prodProp);
        List<ProdPropValue> prodPropValues=propAddDTO.getProdPropValues();
        if (!CollectionUtils.isEmpty(prodPropValues)){
            prodPropValues.forEach(prodPropValue -> {
                prodPropValue.setPropId(prodProp.getPropId());
                this.prodPropValueMapper.insert(prodPropValue);
            });
        }
        return insert;
    }

    /**
     * 查询规格列表
     *
     * @param shopId
     * @return
     */
    @Override
    public List<ProdProp> loadProdProps(Long shopId) {
        return prodPropMapper.selectList(new LambdaQueryWrapper<ProdProp>()
                .eq(ProdProp::getShopId, shopId)
        );
    }

    /**
     * 根据规格id查询规格值列表
     *
     * @param propId
     * @return
     */
    @Override
    public List<ProdPropValue> loadPropVals(Long propId) {
        return prodPropValueMapper.selectList(new LambdaQueryWrapper<ProdPropValue>()
                .eq(ProdPropValue::getPropId, propId)
        );
    }
}




